package com.shuai.api_platform.aop;


import com.shuai.api_platform.client.RedisForItrClient;
import com.shuai.api_platform.common.ErrorCode;
import com.shuai.api_platform.exception.BusinessException;
import com.shuai.api_platform.model.vo.ItrRedisDTO;
import com.shuai.common.service.InnerInterfaceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * 使用AOP实现的接口鉴权
 */


@Aspect
@Component
@Slf4j
public class CommonAdvice {


    @Autowired
    private RedisForItrClient redisForItrClient;


    @DubboReference
    private InnerInterfaceInfoService innerInterfaceInfoService;

    /**
     * 配置切点
     * 匹配controller包下的所有类中的所有public方法
     */
    @Pointcut("execution(public * com.shuai.api_platform.controller.*.*(..))")
    public void authenticationPointCut() {
    }


    @Around("authenticationPointCut()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Object requestStr = getRequestBodyFromArgs(args, methodSignature);
        log.info("用户请求：{}", requestStr);
        String interfaceName = this.getInterfaceName(joinPoint);
        // RPC调用管理系统中的接口信息查询
        Long interfaceId = innerInterfaceInfoService.getInterfaceId(interfaceName);
        if (interfaceId == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "接口不存在");
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object response = joinPoint.proceed();// 执行核心业务
        stopWatch.stop();
        ItrRedisDTO itrRedisDTO = new ItrRedisDTO();
        itrRedisDTO.setInterfaceId(interfaceId);
        itrRedisDTO.setRpsTime(stopWatch.getTotalTimeMillis());
        redisForItrClient.updateItrRank(itrRedisDTO);
        return response;
    }

    private Object getRequestBodyFromArgs(Object[] args, MethodSignature methodSignature) {
        StringBuilder requestBody = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            // 假设请求体参数标记为 @RequestBody
            if (methodSignature.getMethod().getParameters()[i].isAnnotationPresent(RequestBody.class)) {
                return args[i];
            }
        }
        return "";
    }


    private String getInterfaceName(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        return methodSignature.getMethod().getName();
    }
}
